package code.refactoring.Model;

import code.refactoring.View.AskUser;

public class Board {

	private static final int DEFAULT_SIZE = 5;
	private char board[][];
	private int size;

	/**
	 * Creates the array representing the Board
	 */
	public Board() {
		int size = AskUser.askUserForBoardSize();
		this.setSize(size);
		// Create the Board - a 2d array with room for dashes and dots
		size = this.size * 2 - 1;
		board = new char[size][size];
		initializeGameBoard();
	}

	/**
	 * Fill in the empty board with dots and spaces
	 */
	private void initializeGameBoard() {
		for (int row = 0; row < board.length; row++) {
			if (row % 2 == 0) {
				for (int column = 0; column < board[row].length; column++) {
					if (column % 2 == 0) {
						board[row][column] = '.';
					} else {
						board[row][column] = ' ';
					}
				}
			} else {
				for (int column = 0; column < board[row].length; column++) {
					board[row][column] = ' ';
				}
			}
		}
	}

	/**
	 * Gets the size of the game board( not actual size ( it's not modified ))
	 * the size the user asked
	 * 
	 * @return integer representing the size of the game board
	 */
	public int getSize() {
		return size;
	}

	/**
	 * check if size is greater than 1 or else give it the default value
	 * 
	 * @param size
	 *            - size of the game Field
	 */
	public void setSize(int size) {
		if (size > 1) {
			this.size = size;
		} else {
			this.size = DEFAULT_SIZE;
		}
	}

	/**
	 * Get the number of rows of the board (all rows)
	 * 
	 * @return integer number representing the Number of rows
	 */
	public int getRows() {
		if (this.board != null) {
			return this.board.length;
		}
		return 0;
	}

	/**
	 * Get the number of columns of the board (all columns)
	 * 
	 * @return integer number representing the Number of columns
	 */
	public int getColumns() {
		if (this.board != null) {
			return this.board[0].length;
		}
		return 0;
	}

	/**
	 * Gets data from cell with given coordinates
	 * 
	 * @param row
	 *            - selected row
	 * @param column
	 *            - selected column
	 * @return Object representing the data from the Selected cell or returns
	 *         empty char if there is no board or row and/or column are not in
	 *         range
	 */
	public char getDataForCell(int row, int column) {
		if ((this.board != null) && checkIfRowAndColumnAreInRange(row, column)) {
			return this.board[row][column];
		}
		return '\u0000';
	}

	/**
	 * 
	 * check if given row and columns are in range of the Game board
	 * 
	 * @param row
	 *            - row Coordinate to be checked
	 * @param column
	 *            - column Coordinate to be checked
	 * @return boolean Value - true if the row and/ or column is negative or
	 *         bigger then those of the game board
	 */
	protected boolean checkIfRowAndColumnAreInRange(int row, int column) {
		if (((row >= 0) && (column >= 0))
				&& ((row < this.getRows()) && (column < this.getColumns()))) {
			return true;
		}
		return false;
	}

	/**
	 * Check which side the player is moving and insert the approate symbol.
	 * 
	 * @param row
	 *            - row coordinate of the Field where the dash must be
	 * @param col
	 *            - column coordinate of the Field where the dash must be
	 * @param side
	 *            - Direction of the made move (up, down, left and right)
	 */
	public void saveMove(int row, int col, char side) {
		if (checkIfRowAndColumnAreInRange(row, col)) {
			side = Character.toUpperCase(side);
			if (side == 'U')
				this.board[--row][col] = '|';
			else if (side == 'D')
				this.board[++row][col] = '|';
			else if (side == 'L')
				this.board[row][--col] = '-';
			else if (side == 'R')
				this.board[row][++col] = '-';
		}
	}

	/**
	 * Check if selected cell ( by row and column) has a value different then
	 * ' '
	 * 
	 * @param dashRow
	 *            - row of the Field where there must be a dash
	 * @param dashColumn
	 *            - column of the Field where there must be a dash
	 * @return boolean value - true if there is a dash in the Field, false if
	 *         the Field is Empty
	 */
	public boolean checkIfSideHasDash(int dashRow, int dashColumn) {
		return (board[dashRow][dashColumn] == ' ') ? false : true;
	}

	/**
	 * Increases the points of the Given player by one and puts the Player mark
	 * inside of the formed Square
	 * 
	 * @param p
	 *            - object of type Player representing the player which scored a
	 *            point
	 * @param letterBoxRowCoord
	 *            - Row coordinate of the Field where PLayer's mark should be
	 * @param letterBoxColumnCoord
	 *            - Column coordinate of the Field where PLayer's mark should be
	 */
	public void scoredPointLogic(Player p, int letterBoxRowCoord,
			int letterBoxColumnCoord) {
		System.out.println("Player " + p.getName() + " scored a point.");
		p.setPoints(p.getPoints() + 1);
		board[letterBoxRowCoord][letterBoxColumnCoord] = p.getMark();
	}
}
